<template>
  <div class="select-main">
    <div class="select">
      <div
        v-for="item in innerTagData"
        class="tag"
      >
        <div class="tag-content">{{ item.label }}</div>
        <el-icon
          class="tag-close"
          @click="deleteTag(item.id)"
        >
          <CircleCloseFilled />
        </el-icon>
      </div>
    </div>
    <el-button
      @click="openDialog"
      type="primary"
    > 选择 </el-button>
  </div>
  <el-dialog
    v-model="dialogData.show"
    title="选择用户"
    append-to-body
    width="944px"
    custom-class="noticeSelectDialog"
  >
    <AppSearchForm
      @submit="search"
      @reset="reset"
    >
      <el-form-item>
        <el-input
          v-model="query.name"
          clearable
          placeholder="输入姓名、用户姓名"
          style="width: 200px"
        />
      </el-form-item>
    </AppSearchForm>
    <div style="position: relative; top: 30px">已选用户</div>
    <div>
      <el-table
        border
        stripe
        :data="tableData.data"
        v-loading="tableData.option.loading"
        @select="handleSelection"
        @select-all="handleSelectionAll"
        class="table"
        ref="table"
      >
        <el-table-column
          type="selection"
          width="35"
        />
        <el-table-column
          show-overflow-tooltip
          prop="id"
          label="用户编号"
          width="150"
        />
        <el-table-column
          show-overflow-tooltip
          prop="username"
          label="登入账号"
        />
        <el-table-column
          show-overflow-tooltip
          prop="phone"
          label="手机号"
        />
        <el-table-column
          show-overflow-tooltip
          prop="realName"
          label="用户姓名"
        />
        <el-table-column
          prop="enabled"
          label="状态"
          width="50"
        >
          <template #default="scope">
            {{ scope.row.enabled ? "启用" : "禁用" }}
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        background
        layout="total,sizes,prev, pager, next,jumper"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :total="tableData.option.total"
        :page-size="tableData.option.pageSize"
        :page-sizes="tableData.option.pageSizes"
        :current-page="tableData.option.page"
        style="text-align: right; margin-top: 10px; margin-bottom: 10px"
      >
      </el-pagination>
    </div>

    <AppPageTable
      stripe
      :data="innerTagData"
      :isPagination="true"
      class="select-table"
    >
      <el-table-column
        prop="label"
        label="用户姓名"
      > </el-table-column>
      <el-table-column
        label="操作"
        width="50px"
      >
        <template #default="scope">
          <el-button
            @click="deleteTag(scope.row.id)"
            link
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </AppPageTable>
    <template #footer>
      <span class="dialog-footer">
        <el-button
          type="primary"
          @click="confirm"
        > 确认 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch } from "vue";
import AppSearchForm from "@/components/AppSearchForm.vue";
import AppPageTable, { useTableOption } from "@/components/AppPageTable2";
import httpInstance from "@/public/request";
import { nextTick } from "vue";

interface tag {
  readonly id: string | number;
  label: string;
}

interface Props {
  //作为v-model
  tagData: Array<tag>;
}

const props = withDefaults(defineProps<Props>(), {
  tagData: () => [],
});

const innerTagData = ref(props.tagData);
const emit = defineEmits(["update:tagData"]);

function deleteTag(id: number | string): void {
  let deindex: number = innerTagData.value.findIndex((item) => {
    return item.id == id;
  });
  innerTagData.value.splice(deindex, 1);
  updateRowSelect();
  emit("update:tagData", innerTagData);
}

// 当弹窗关闭的时候，清空之前选择用户
function resetDefault() {
  innerTagData.value = [];
  emit("update:tagData", innerTagData);
}

const table = ref();

const dialogData = reactive({
  show: false,
});
watch(
  () => dialogData.show,
  (newVal) => {
    if (newVal) {
      nextTick(() => {
        updateRowSelect();
      });
    }
  }
);
function openDialog() {
  dialogData.show = true;
}
function confirm() {
  dialogData.show = false;
}
const query = reactive({
  name: "",
  account: "",
});

function updateRowSelect() {
  if (dialogData.show) {
    tableData.data.forEach((item: any) => {
      const isIncluded = innerTagData.value.some(
        (inItem) => item.id == inItem.id
      );
      if (isIncluded) {
        table.value!.toggleRowSelection(item, true);
      } else {
        table.value!.toggleRowSelection(item, false);
      }
    });
  }
}

function search() {
  tableData.option.loading = true;
  httpInstance
    .get("/api/user/query", {
      KeyWords: query.name,
      PageIndex: tableData.option.page,
      PageSize: tableData.option.pageSize,
    })
    .then((res) => {
      tableData.data = res.content;
      tableData.option.total = res.totalElements;
      if (dialogData.show) {
        updateRowSelect();
      }
    })
    .finally(() => {
      tableData.option.loading = false;
    });
}

function reset() {
  query.name = "";
  query.account = "";
  search();
}

const tableData = reactive({
  data: [],
  option: useTableOption({
    pageSize: 5,
    pageSizes: [5, 10],
  }),
});

function handleSizeChange() {
  tableData.option.page = 1;
  search();
}

function handlePageChange() {
  search();
}

function handleSelection(selection: any, row: any) {
  updateSelectData(row, true);
}

function handleSelectionAll(selection: any) {
  if (selection.length == 0) {
    tableData.data.forEach(item => {
      updateSelectData(item, false, false)
    })
  } else {
    tableData.data.forEach(item => {
      updateSelectData(item, false, true)
    })
  }
}
/**
 * 更新v-model数据
 * 是单条更新 有就删除 没有添加
 * 不是单条更新 根据全选内容 全取消则删除表格内数据 全勾选则全部添加
 * @param data - 表格数据
 * @param single - 判断是不是单条
 * @param select - 判断是不是全勾选
 */
function updateSelectData(data: any, single: boolean, select?: boolean) {
  let existindex: number = innerTagData.value.findIndex((item) => {
    return item.id == data.id;
  });
  if (single) {
    if (existindex != -1) {
      innerTagData.value.splice(existindex, 1);
    } else {
      innerTagData.value.push({
        id: data.id,
        label: data.username,
      });
    }
  } else {
    if (select) {
      if (existindex == -1) {
        innerTagData.value.push({
          id: data.id,
          label: data.username,
        });
      }
    } else {
      if (existindex != -1) {
        innerTagData.value.splice(existindex, 1);
      }
    }
  }

  emit("update:tagData", innerTagData);
}

defineExpose({
  resetDefault
})

onMounted(() => {
  search();
});
</script>

<style scoped lang="scss">
.select-main {
  display: flex;
  width: 100%;
}

.select {
  width: 200px;
  display: inline-flex;
  flex-grow: 1;
  align-items: center;
  justify-content: flex-start;
  padding: 1px 11px;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  margin-right: 10px;
  flex-wrap: wrap;

  .tag {
    color: #909399;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    vertical-align: middle;
    height: 24px;
    padding: 0 9px;
    font-size: 12px;
    line-height: 1;
    border-width: 1px;
    border-style: solid;
    border-radius: 4px;
    margin-right: 4px;
    margin-bottom: 2px;

    .tag-content {
      margin-right: 2px;
    }

    .tag-close {
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
      cursor: pointer;
      height: 12px;
      width: 12px;
      font-size: 10px;
      transition: all 0.3s;
      opacity: 0;
    }
  }

  .tag:last-child {
    margin-right: 0px;
  }

  .tag-close:hover {
    color: #fff;
    background-color: #909399;
    opacity: 1;
  }
}

.table {
  height: 300px;

  :deep(.el-checkbox) {
    height: auto;
  }

  :deep(.el-table__header-wrapper) th {
    font-size: 14px;
    background-color: #f7f8fa !important;
  }
}

.table-header {
  font-size: 14px;
  background-color: #f7f8fa !important;
}

.select-table {
  :deep(.el-button) {
    padding: 0;
    min-height: auto;
  }
}
</style>

<style>
.noticeSelectDialog .el-dialog__body {
  display: grid;
  grid-template-columns: 3fr 1fr;
  grid-template-rows: 50px 1fr;
  gap: 10px;
  height: 100%;
}
</style>
